#include "CyNetText.h"
#include <Windows.h>
using namespace std;

CyNetText::CyNetText(void)
{
}

CyNetText::CyNetText(const wstring& text) : _text(text)
{
}

CyNetText::~CyNetText(void)
{
}

int CyNetText::GetSize() const
{
	const wchar_t * str = _text.c_str();
	int len = _text.length();
	return WideCharToMultiByte(CP_UTF8, 0,
		str, len, 0, 0, 0, 0) + 12;
}

int CyNetText::GetStream(char* buffer, int size) const
{
	char * pBuffer = buffer;

	// 1. write code field
	pBuffer = buffer + 4;
	int code = CyNetObjectEnum::TEXT;
	*reinterpret_cast<int*>(pBuffer) = code;

	// 2. write text field
	pBuffer = buffer + 12;
	int l = WideCharToMultiByte(CP_UTF8, 0, _text.c_str(),
		_text.length(), pBuffer, size - 8, 0, 0);

	// 3. Write Size
	int len = l + 12;
	pBuffer = buffer;
	*reinterpret_cast<int*>(pBuffer) = len;

	// 4. Write checksum
	pBuffer = buffer + 8;
	*reinterpret_cast<int*>(pBuffer) = code ^ len;

	return len;
}

CyNetText& CyNetText::FromStream(const char* buffer)
{
	int textSize = *reinterpret_cast<const int*>(buffer) - 12;
	wchar_t * wbuffer = new wchar_t[textSize + 1];

	int textLen = MultiByteToWideChar(CP_UTF8,
		0, buffer + 12, textSize, wbuffer, textSize);

	wbuffer[textLen] = 0;

	_text = wbuffer;

	return *this;
}

CyNetObjectEnum CyNetText::GetType() const
{
	return CyNetObjectEnum::TEXT;
}

wstring& CyNetText::GetText(wstring& buffer) const
{
	buffer = _text;
	return buffer;
}

CyNetText& CyNetText::SetText(const wstring& buffer)
{
	_text = buffer;
	return *this;
}